package org.groovyflow.spring.web;


import groovy.lang.Binding;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.groovyflow.spring.locator.BeanLocator;
import org.groovyflow.spring.locator.BeanLocatorImpl;
import org.groovyflow.spring.web.prettyURL.PrettyURLResponse;
import org.groovyflow.spring.web.prettyURL.SafeRedirect;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class RouterController implements Controller {
    private BeanLocator beanLocator = new BeanLocatorImpl();
    
    private static final String REDIRECT = "redirect:";
    private SafeRedirect safeRedirect = new SafeRedirect();
   
	public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
		if(isPrettyURLScheme())
			res = PrettyURLResponse.newInstance(res, getFullPath(req), getSafeRedirect());
	    return this.getEngineManager().isNonCompiledMode() ? doNonCompiled(req, res) : doCompiled(req, res);
	}
	
    protected ModelAndView doNonCompiled(HttpServletRequest req, HttpServletResponse res) throws Exception {
		Binding binding = new Binding();
		binding.setVariable("request", req);
		binding.setVariable("response", res);
		binding.setVariable("beanLocator", this.beanLocator);
		this.getEngineManager().run("controllerScript.groovy", binding);  //TODO  Maybe make controllerScript.groovy a paramater
		return procesModelAndView( binding.getVariable("modelAndView"), req);
		
    }

    private ModelAndView doCompiled(HttpServletRequest req, HttpServletResponse res) throws Exception {
    	ClassLoader classLoader = this.getClass().getClassLoader();
    	 return procesModelAndView( this.getDynamicFinder().invoke(req, res, classLoader), req);
    }


    //TODO  Possibly provide a default jsp if one isn't already there.
    //The default will be based on info in the request.
    protected ModelAndView procesModelAndView(Object mv, HttpServletRequest req){
    	ModelAndView m = (ModelAndView) mv;
    	if(m == null || !isPrettyURLScheme())
    		return m;
    	String viewName = m.getViewName();
    	if(!viewName.contains(REDIRECT))
    		   return m;
    	
    	viewName = StringUtils.replace(viewName, REDIRECT, "");
    	String processedViewName = this.getSafeRedirect().makeSafeRedirect(viewName, this.getFullPath(req));
    	if(viewName.equals(processedViewName))
    		return m;
    	ModelAndView newOne = new ModelAndView(REDIRECT + processedViewName, m.getModel());
    	
    	return newOne;
    }

	
	public void setBeanLocator(BeanLocator beanLocator) {
		this.beanLocator = beanLocator;
	}
	
	protected ControllerGroovyScriptEngineManager getEngineManager(){
		return (ControllerGroovyScriptEngineManager) 
			this.beanLocator.getBean("controllerGroovyScriptEngineManager");
	}
	
	protected DynamicFinder getDynamicFinder(){
		return (DynamicFinder) 
			this.beanLocator.getBean("dynamicFinder");		
	}
	
	private String getFullPath(HttpServletRequest request){
		System.out.println("entering getFullPath");
		StringBuffer buf = new StringBuffer();
		buf.append(request.getScheme()).append("://").append(request.getServerName()).
			append(":").append(request.getServerPort()).append(request.getContextPath()).
			append("/");
		return buf.toString();
	}
	
	public boolean isPrettyURLScheme() {
		return getDynamicFinder().isPrettyURLScheme();
	}	
	
	protected SafeRedirect getSafeRedirect(){
		return this.safeRedirect;
	}
}
